package sliver.dao.impl;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

import org.hibernate.Query;
import org.hibernate.SQLQuery;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

import sliver.dao.BaseDao;

@Repository
public class BaseDaoImpl<T extends Serializable> implements BaseDao<T>{
	
	@Autowired
	private SessionFactory sessionFactory;
	
	public BaseDaoImpl(){
		
	}
	
	@Override
	public T findById(Serializable id, Class<T> entityClass) {
		return entityClass.cast(getCurrentSession().get(entityClass, id));
	}

	@Override
	public List<T> findAll(Class<T> entityClass) {
		
		String entityName = entityClass.getName();
		
		String queryString = "SELECT e FROM " + entityName + " e";
		
		return complexQuery(queryString, new Object[]{});
	}

	@Override
	public T deleteById(Serializable id, Class<T> entityClass) {
		
		T entity = findById(id, entityClass);
		
		if(entity != null){
			getCurrentSession().delete(entity);
			return entity;
		}
		
		return null;
	}

	@Override
	public T update(T entity) {
		getCurrentSession().update(entity);
		return entity;
	}

	@Override
	public Serializable insert(T entity) {
		return getCurrentSession().save(entity);
	}

	@Override
	public List<T> complexQuery(String queryString, Object[] params) {
		
		Query query = getCurrentSession().createQuery(queryString);
		for(int index = 0; index < params.length; index++ ){
			query.setParameter(index, params[index]);
		}
		
		@SuppressWarnings("unchecked")
		List<T> entities = query.list();
		
		if(entities == null)
			return new ArrayList<T>();
		
		return entities;
	}
	
	@Override
	public List<Object> complexQueryFields(String queryString, Object[] params) {
		SQLQuery query = getCurrentSession().createSQLQuery(queryString);
		for(int index = 0; index < params.length; index++ ){
			query.setParameter(index, params[index]);
		}
		
		@SuppressWarnings("unchecked")
		List<Object> entities = query.list();
		
		if(entities == null)
			return new ArrayList<Object>();
		
		return entities;
	}
	
	protected Session getCurrentSession(){
		return sessionFactory.getCurrentSession();
	}
}
